package Q7_06_Jigsaw; import java.util.LinkedList; import java.util.Random; public class Question { public static Edge createRandomEdge(String code) { Random random = new Random(); Shape type = Shape.INNER; if (random.nextBoolean()) { type = Shape.OUTER; } return new Edge(type, code); } public static Edge[] createEdges(Piece[][] puzzle, int column, int row) { String key = column + ":" + row + ":"; /* Get left edge */ Edge left = column == 0 ? new Edge(Shape.FLAT, key + "h|e") : puzzle[row][column - 1].getEdgeWithOrientation(Orientation.RIGHT)._createMatchingEdge(); /* Get top edge */ Edge top = row == 0 ? new Edge(Shape.FLAT, key + "v|e") : puzzle[row - 1][column].getEdgeWithOrientation(Orientation.BOTTOM)._createMatchingEdge(); /* Get right edge */ Edge right = column == puzzle[row].length - 1 ? new Edge(Shape.FLAT, key + "h|e") : createRandomEdge(key + "h"); /* Get bottom edge */ Edge bottom = row == puzzle.length - 1 ? new Edge(Shape.FLAT, key + "v|e") : createRandomEdge(key + "v"); Edge[] edges = {left, top, right, bottom}; return edges; } public static LinkedList<Piece> initializePuzzle(int size) { /* Create completed puzzle. */ Piece[][] puzzle = new Piece[size][size]; for (int row = 0; row < size; row++) { for (int column = 0; column < size; column++) { Edge[] edges = createEdges(puzzle, column, row); puzzle[row][column] = new Piece(edges); } } /* Shuffle and rotate pieces. */ LinkedList<Piece> pieces = new LinkedList<Piece>(); Random r = new Random(); for (int row = 0; row < size; row++) { for (int column = 0; column < size; column++) { int rotations = r.nextInt(4); Piece piece = puzzle[row][column]; piece.rotateEdgesBy(rotations); int index = pieces.size() == 0 ? 0 : r.nextInt(pieces.size()); pieces.add(index, piece); } } return pieces; } public static String solutionToString(Piece[][] solution) { StringBuilder sb = new StringBuilder(); for (int h = 0; h < solution.length; h++) { for (int w = 0; w < solution[h].length; w++) { Piece p = solution[h][w]; if (p == null) { sb.append("null"); } else { sb.append(p.toString()); } } sb.append("\n"); } return sb.toString(); } /* Used for testing. Check if puzzle is solved. */ public static boolean validate(Piece[][] solution) { if (solution == null) return false; for (int r = 0; r < solution.length; r++) { for (int c = 0; c < solution[r].length; c++) { Piece piece = solution[r][c]; if (piece == null) return false; if (c > 0) { /* match left */ Piece left = solution[r][c-1]; if (!left.getEdgeWithOrientation(Orientation.RIGHT).fitsWith(piece.getEdgeWithOrientation(Orientation.LEFT))) { return false; } } if (c < solution[r].length - 1) { /* match right */ Piece right = solution[r][c+1]; if (!right.getEdgeWithOrientation(Orientation.LEFT).fitsWith(piece.getEdgeWithOrientation(Orientation.RIGHT))) { return false; } } if (r > 0) { /* match top */ Piece top = solution[r-1][c]; if (!top.getEdgeWithOrientation(Orientation.BOTTOM).fitsWith(piece.getEdgeWithOrientation(Orientation.TOP))) { return false; } } if (r < solution.length - 1) { /* match bottom */ Piece bottom = solution[r+1][c]; if (!bottom.getEdgeWithOrientation(Orientation.TOP).fitsWith(piece.getEdgeWithOrientation(Orientation.BOTTOM))) { return false; } } } } return true; } public static boolean testSize(int size) { LinkedList<Piece> pieces = initializePuzzle(size); Puzzle puzzle = new Puzzle(size, pieces); puzzle.solve(); Piece[][] solution = puzzle.getCurrentSolution(); System.out.println(solutionToString(solution)); boolean result = validate(solution); System.out.println(result); return result; } public static void main(String[] args) { for (int size = 1; size < 10; size++) { if (!testSize(size)) { System.out.println("ERROR: " + size); } } } }